package com.co.common.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * 第三方登录，检验授权凭证
 * 
 */
public class OtherLoginUtil {

	public static Logger log = LoggerFactory.getLogger(OtherLoginUtil.class);

	// 微信登录
	
	/** 重定向 URL */
	public final static String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect";
	
	/** 获取UnionId URL */
	public final static String TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	
	
	// QQ登录
	/** 获取code */
	public final static String QQ_AUTHORIZE_URL="https://graph.qq.com/oauth/show?which=Login&display=pc&response_type=code&client_id=APPID&redirect_uri=REDIRECT_URI&scope=get_user_info";
	
	/** 获得access_token */
	public final static String QQ_TOKEN_URL="https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=APPID&client_secret=APPKEY&code=CODE&redirect_uri=REDIRECT_URI";
	
	/** 获得openId */
	public final static String QQ_OPENID_URL="https://graph.qq.com/oauth2.0/me?access_token=ACCESS_TOKEN";
	
	
	/**
	 * 获取微信重定向URL
	 * @return
	 */
	public static String getRedirectUrl(String appIdText,String authorize_url,String basePath, String sourceUrl) {
		String appid = PcPropertiesUtil.getProperty(appIdText);
		//跳转必须去掉:80
		basePath = basePath.replace(":80", "");
		String redirectUrl = authorize_url.replace("APPID", appid).replace("REDIRECT_URI", basePath+sourceUrl);
		return redirectUrl;
	}
	
	/**
	 * 获得微信unionId
	 * @param code
	 * @return
	 */
	public static String getUnionId(String code) {
		String appid = PcPropertiesUtil.getProperty("op_appid");
		String appsecret = PcPropertiesUtil.getProperty("op_appsecret");
		String requestUrl = TOKEN_URL.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
		Map<String, Object> mapResult = httpsRequest(requestUrl, "GET", null);
//		Gson gson = new Gson();
//		String json = gson.toJson(mapResult);
//		log.info("mapResult****************"+json);
		String unionId = null;
		// 如果请求成功
		if (null != mapResult) {
			unionId = (String) mapResult.get("unionid");
			log.info("wechat getUnionId success UnionId = " + unionId);
		}else{
			log.error("wechat getUnionId fail requestUrl = " + requestUrl);
		}
		return unionId;
	}
	
	public static String getQqOpenId(String code,String basePath, String sourceUrl) {
		// 获得qq登录openId
		String appid = PcPropertiesUtil.getProperty("qq_appid");
		String appkey = PcPropertiesUtil.getProperty("qq_appkey");
		String requestUrl1 = QQ_TOKEN_URL.replace("APPID", appid).replace("APPKEY", appkey).replace("CODE", code).replace("REDIRECT_URI", basePath+sourceUrl);
		Map<String, Object> mapResult = httpsRequest4Url(requestUrl1, "GET", null);
		String qqOpenId = null;
		if (null != mapResult) {
			String access_token = (String) mapResult.get("access_token");
			log.info(" qqLogin get access_token success = " + access_token);
			String requestUrl2 = QQ_OPENID_URL.replace("ACCESS_TOKEN", access_token);
			Map<String, Object> mapResult2 = httpsRequest4CallBack(requestUrl2, "GET", null);
			if (null != mapResult2) {
				
				qqOpenId = (String) mapResult2.get("openid");
				log.info("qqLogin get openid success= " + qqOpenId);
			}else{
				log.error("qqLogin get openid success = " + requestUrl2);
			}
		}else{
			log.error("qqLogin get access_token success  requestUrl = " + requestUrl1);
		}
		
		
		return qqOpenId;
	}
	
	
	/**
	 * 发起https请求并获取结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr  提交的数据
	 * @return Map
	 */
	private static Map<String, Object> httpsRequest(String requestUrl,String requestMethod, String outputStr) {
		Map<String, Object> mapResult = null;
		StringBuffer buffer = SSLRequest(requestUrl, requestMethod, outputStr);
		Gson gson = new Gson();
		mapResult = gson.fromJson(buffer.toString(),
				new TypeToken<HashMap<String, Object>>() {
		}.getType());
		return mapResult;
	}
	
	private static Map<String, Object> httpsRequest4Url(String requestUrl,String requestMethod, String outputStr) {
		Map<String, Object> mapResult = null;
		requestUrl = requestUrl.replace(":80", "");
		StringBuffer buffer = SSLRequest(requestUrl, requestMethod, outputStr);
		mapResult = UrlMapUtil.getUrlParams(buffer.toString());
		return mapResult;
	}
	
	private static Map<String, Object> httpsRequest4CallBack(String requestUrl,String requestMethod, String outputStr) {
		Map<String, Object> mapResult = null;
		requestUrl = requestUrl.replace(":80", "");
		StringBuffer buffer = SSLRequest(requestUrl, requestMethod, outputStr);
		String str=buffer.toString().replace("callback(", "").replace(");", "");
		Gson gson = new Gson();
		mapResult = gson.fromJson(str,
				new TypeToken<HashMap<String, Object>>() {
		}.getType());
		return mapResult;
	}

	
	
	
	/**
	 * SSL 方式获得 StringBuffer
	 * @param requestUrl
	 * @param requestMethod
	 * @param outputStr
	 * @return
	 */
	private static StringBuffer SSLRequest(String requestUrl,
			String requestMethod, String outputStr) {
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();
			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);

			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod)) {
				httpUrlConn.connect();
			}

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
		} catch (ConnectException ce) {
			log.error("server connection timed out.");
		} catch (Exception e) {
			log.error("https request error:", e);
		}
		return buffer;
	}

}